package keer.httpinterface.http;

import keer.httpinterface.annotation.HttpInterface;
import keer.httpinterface.annotation.Request;
import keer.httpinterface.utils.AnnotationInfo;
import keer.httpinterface.utils.AnnotationUtils;
import keer.httpinterface.utils.CacheMap;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;

public class DefaultHttpRequestContext {
    private final static CacheMap<CacheKey, DefaultHttpRequestContext> CONTEXT_CACHE = new CacheMap<>();
    private static final String KEY_URL = "url";
    private static final String KEY_HEADERS = "headers";
    private static final String KEY_PARAMS = "params";
    private static final String KEY_METHOD = "method";
    private static final String KEY_CHARSET = "charset";
    private static final String KEY_CONTENT_TYPE = "contentType";
    //    private static final String KEY_CONTENT_TYPE_STRING = "contentTypeString";
    private static final String KEY_INTERCEPTORS = "interceptors";
    private Headers headers;
    private HttpParams params;
    private String url;
    private HttpMethod method;
    private Class<?> interfaceClass;
    private Method interfaceMethod;
    private AnnotationInfo httpInterfaceAnnotation;
    private AnnotationInfo requestAnnotation;

    private DefaultHttpRequestContext() {

    }

    public Headers getHeaders() {
        return headers;
    }

    public HttpParams getParams() {
        return params;
    }

    public String getUrl() {
        return url;
    }

    public HttpMethod getMethod() {
        return method;
    }

    public Class<?> getInterfaceClass() {
        return interfaceClass;
    }

    public Method getInterfaceMethod() {
        return interfaceMethod;
    }

//    public static HttpRequestContext create(Class<?> interfaceClass,
//                                            Method interfaceMethod) {
//        return CONTEXT_CACHE.loadOrCreate(new CacheKey(interfaceClass, interfaceMethod), () -> {
//            HttpRequestContext context = new HttpRequestContext();
//            initContext(interfaceClass, interfaceMethod, context);
//            return context;
//        });
//    }
//
//    private static void initContext(Class<?> interfaceClass,
//                                    Method interfaceMethod,
//                                    HttpRequestContext context) {
//        context.interfaceMethod = interfaceMethod;
//        context.interfaceClass = interfaceClass;
//        context.httpInterfaceAnnotation = AnnotationUtils.getDeclaredAnnotation(interfaceClass,
//                HttpInterface.class, Boolean.TRUE);
//        context.requestAnnotation = AnnotationUtils.getMethodAnnotation(interfaceMethod,
//                Request.class, Boolean.TRUE);
//        context.url = (String) context.httpInterfaceAnnotation.get(KEY_URL);
//    }

    private static class CacheKey {
        private final Class<?> interfaceClass;
        private final Method interfaceMethod;
        private CacheKey(Class<?> interfaceClass,
                         Method interfaceMethod) {
            this.interfaceClass = interfaceClass;
            this.interfaceMethod = interfaceMethod;
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof CacheKey)) {
                return false;
            }
            CacheKey c = (CacheKey) obj;
            return interfaceClass == c.interfaceClass &&
                    interfaceMethod == c.interfaceMethod;
        }

        @Override
        public int hashCode() {
            return Objects.hash(interfaceClass, interfaceMethod);
        }
    }

    private static class ArgInfo {
        private int index;
        private String name;
        private Field field;

        private ArgInfo(int index, String name) {
            this(index, name, null);
        }

        private ArgInfo(int index, String name, Field field) {
            this.index = index;
            this.name = name;
            this.field = field;
        }
    }
}
